package com.ef.web.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.TypeVariable;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.util.ServletContextAware;

import com.ef.constant.SystemContant;
import com.ef.domain.User;
import com.ef.service.BaseService;
import com.ef.util.PaginationSupport;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.conversion.annotations.Conversion;

@SuppressWarnings("serial")
@Conversion()
public abstract class BaseAction<T> extends ActionSupport implements
		ModelDriven<T>, Preparable, ServletContextAware {
	protected final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
			.getLog(BaseAction.class);
	public static final int DEFAULT_PAGESIZE = 14;

	public static final String LIST = "list";
	public static final String EDIT = "edit";
	public static final String VIEW = "view";
	public static final String CONFIRM = "confirm";
	public static final String DELETE = "delete";
	public static final String LOGIN = "login";
	public static final String LOGIN_SUCCESS = "loginSuccess";
	public static final String NOLOGIN = "nologin";
	public static final String LEFT = "left";
	public static final String CALL = "call";
	public static final String OK = "ok";

	protected String result="";
	
	protected String infoTitle="Congratulations";
	
	protected String homepage="list";
	
	protected String infoimg="ok";
	
	protected Class<T> entityClass;
	protected T entity;
	protected BaseService baseService;
	protected Long id;

	protected int startIndex = 0;
	protected int pageSize = DEFAULT_PAGESIZE;

	protected PaginationSupport<T> listResult;

	protected ServletContext sc;

	@SuppressWarnings("unchecked")
	public BaseAction() {
		try {
			TypeVariable[] typeVariables = getClass()
					.getSuperclass().getTypeParameters(); 
			if (typeVariables != null && typeVariables.length > 0) {
				entityClass = (Class<T>) ((ParameterizedType) getClass()
						.getGenericSuperclass()).getActualTypeArguments()[0];
				return;
			} ;
		} catch (Exception ex) {
			log.warn("无法获取模型的类");
		}
		// 再找父类,允许一次继承
		try {
			entityClass = (Class<T>) ((ParameterizedType) getClass()
					.getSuperclass().getGenericSuperclass())
					.getActualTypeArguments()[0];
			return;
		} catch (Exception ex) {
			log.warn("无法获取模型的类");
		}
	}

	public T getModel() {
		if (entity == null) {
			try {
				entity = (T) entityClass.newInstance();
			} catch (Exception e) {
				log.warn("无法创建模型实例");
				return null;
			}
		}
		return entity;
	}

	@SuppressWarnings("unchecked")
	public void prepare() throws Exception {
		if (id == null || id < 1) {
			if (entity == null) {// CYG
				entity = (T) entityClass.newInstance();
				prepareModelInner(entity);
			}
		} else {
			entity = (T) baseService.getHibernateTemplate().load(entityClass,
					id);
		}
	}

	/**
	 * 模型新建时候的特殊处理，子类可以继承
	 * 
	 * @param model
	 */
	protected void prepareModelInner(T model) {

	}

	protected void setSessionUser(User user) {
		Map<String, Object> session = ActionContext.getContext().getSession();
		session.put(SystemContant.CURRENT_USER, user);
	};
	

	

	protected User getSessionUser() {
		Map<String, Object> session = ActionContext.getContext().getSession();
		User user = (User) session.get(SystemContant.CURRENT_USER);
        if (user==null){
        	try {
        		String path = getRequest().getContextPath();
        		String basePath = getRequest().getScheme() + "://"
    			+ getRequest().getServerName() + ":" + getRequest().getServerPort()
    			+ path + "/";
				ServletActionContext.getResponse().sendRedirect(basePath+"login.jsp");
				return null;
			} catch (IOException e) {
				 log.error("getSessionUser Error:"+e);
			}
        }
		return user;
	}

	protected void clearSessionUser() {
		Map<String, Object> session = ActionContext.getContext().getSession();
		session.remove(SystemContant.CURRENT_USER);
	}

	public String getRandImageCode() {
		Map<String, Object> session = ActionContext.getContext().getSession();
		return (String) session.get(SystemContant.CURRENT_IMAGECODE);
	}

	protected HttpSession getSession() {
		HttpSession session = ServletActionContext.getRequest().getSession();
		return session;
	}

	protected HttpSession getSession(boolean forceCreate) {
		HttpSession session = ServletActionContext.getRequest().getSession(
				forceCreate);
		return session;
	}

	protected HttpServletRequest getRequest() {
		return ServletActionContext.getRequest();
	}

	protected HttpServletResponse getResponse() {
		return ServletActionContext.getResponse();
	}

	public BaseService getBaseService() {
		return baseService;
	}

	public void setBaseService(BaseService baseService) {
		this.baseService = baseService;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public int getStartIndex() {
		return startIndex;
	}

	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public PaginationSupport<T> getListResult() {
		return listResult;
	}

	public void setListResult(PaginationSupport<T> listResult) {
		this.listResult = listResult;
	}

	public void setServletContext(ServletContext sc) {
		this.sc = sc;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	
	public String response(String rsp) {
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setHeader("Cache-Control", "no-cache");
		response.setContentType("text/xml;charset=GBK ");
		PrintWriter out = null;
		try {
			String responseStr = "<?xml version=\"1.0\" encoding=\"gb2312\"?>"
					+ "<response>" + rsp + "</response>";
			out = response.getWriter();
			out.print(responseStr);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (Exception e) {

				}
			}
		}
		return null;
	}

	public String responseError(String message) {
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setHeader("Cache-Control", "no-cache");
		response.setContentType("text/xml;charset=GBK ");
		PrintWriter out = null;
		try {
			String responseStr = "<?xml version=\"1.0\" encoding=\"gb2312\"?>"
					+ "<response>" + "<errorinfo>" + message + "</errorinfo>"
					+ "</response>";
			out = response.getWriter();
			out.print(responseStr);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (Exception e) {

				}
			}
		}
		return null;
	}

	public void resultOK(String result,String homepage){
		this.infoimg="ok";
		this.infoTitle="Congratulations";
		this.result=result;
		this.homepage=homepage;
	}
	public void resultWarn(String result,String homepage){
		infoimg="warn";
		this.infoTitle="Warn";
		this.result=result;
		this.homepage=homepage;
	}
	public void resultError(String result,String homepage){
		infoimg="error";
		this.infoTitle="Sorry";
		this.result=result;
		this.homepage=homepage;
	}
	public String getInfoTitle() {
		return infoTitle;
	}

	public void setInfoTitle(String infoTitle) {
		this.infoTitle = infoTitle;
	}

	public String getHomepage() {
		return homepage;
	}

	public void setHomepage(String homepage) {
		this.homepage = homepage;
	}

	public String getInfoimg() {
		return infoimg;
	}

	public void setInfoimg(String infoimg) {
		this.infoimg = infoimg;
	}
}
